home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved.
- *
- * (b) If this Sample Code is distributed as part of the Display PostScript
- * System Software Development Kit from Adobe Systems Incorporated,
- * then this copy is designated as Development Software and its use is
- * subject to the terms of the License Agreement attached to such Kit.
- *
- * (c) If this Sample Code is distributed independently, then the following
- * terms apply:
- *
- * (d) This file may be freely copied and redistributed as long as:
- * 1) Parts (a), (d), (e) and (f) continue to be included in the file,
- * 2) If the file has been modified in any way, a notice of such
- * modification is conspicuously indicated.
- *
- * (e) PostScript, Display PostScript, and Adobe are registered trademarks of
- * Adobe Systems Incorporated.
- *
- * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
- * CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
- * AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
- * ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
- * OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
- * WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
- * WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
- * DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
- * OF THIRD PARTY RIGHTS.
- */
-
- /*
- * epsfwriter.c
- *
- * Version: 2.0
- * Author: Ken Fromm
- * History:
- * 03-07-91 Added this comment.
- */
-
- #import <appkit/NXBitmapImageRep.h>
- #import <appkit/color.h>
- #import <appkit/graphics.h>
- #import <appkit/nextstd.h>
- #import <appkit/tiff.h>
-
- #import <dpsclient/dpsclient.h>
- #import <dpsclient/wraps.h>
- #import <objc/List.h>
- #import <objc/hashtable.h>
- #import <streams/streamsimpl.h>
- #import <streams/streams.h>
-
- #import "ImportApp.h"
- #import "epsfstruct.h"
- #import "epsfwraps.h"
-
- #define MAX_CHARS 255
- #define MAX_BYTES (MAX_CHARS/2)
-
- extern void GetDocumentComment();
- extern NXColor GetColorAt(NXBitmapImageRep *image, int x, int y);
- extern void LogEpsfError();
-
- /*
- * These arrays contain the proper instructions for including, initiating
- * and terminating procedure sets using the Adobe Illustrator format.
- */
- const static char EpsfProcSetDef[ ] =
- "% EPSF_Illustrator_abbrev
- % Version 1.0 8/23/1990
- % Copyright (C) 1987, 1988, 1989, 1990
- % Adobe Systems Incorporated
- % All Rights Reserved
-
- userdict /EPSF_Illustrator_abbrev 14 dict dup begin put
- % initialization
- /initialize % - initialize -
- {
- userdict /EPSF_Illustrator_abbrev_vars 1 dict dup begin put
- /_i null def
- EPSF_Illustrator_abbrev begin
- EPSF_Illustrator_abbrev
- {
- dup xcheck
- {
- bind
- } if
- pop pop
- } forall
- end
- end
- EPSF_Illustrator_abbrev begin
- EPSF_Illustrator_abbrev_vars begin
- newpath
- } def
-
- /terminate % - terminate -
- {
- end
- end
- } def
-
- /ddef % key value ddef -
- {
- EPSF_Illustrator_abbrev_vars 3 1 roll put
- } def
-
- /npop % integer npop -
- {
- {
- pop
- } repeat
- } def
-
- % color operators
- /g % gray g -
- {
- setgray
- } def
-
- % graphic state operators
- /d % array phase d -
- {
- setdash
- } def
- /cf % - cf flatness
- currentflat def
- /i % flatness i -
- {
- dup 0 eq
- {
- pop cf
- } if
- setflat
- } def
- /j % linejoin j -
- {
- setlinejoin
- } def
- /J % linecap J -
- {
- setlinecap
- } def
- /M % miterlimit M -
- {
- setmiterlimit
- } def
- /w % linewidth w -
- {
- setlinewidth
- } def
-
- % place operators
- /` % matrix llx lly urx ury string ` -
- {
- /_i save ddef
- pop 5 -1 roll concat
- newpath 4 2 roll 2 copy moveto
- 3 1 roll 1 index lineto
- 2 index exch lineto
- lineto
- closepath
- clip newpath
- userdict begin
- /showpage {} def
- } def
-
- /~ % - ~ -
- {
- end
- _i restore
- } def
-
- currentdict readonly pop end\n";
-
- const static char EpsfProcSetInit[ ] = "EPSF_Illustrator_abbrev /initialize get exec\n";
-
- const static char EpsfProcSetTerm[ ] = "EPSF_Illustrator_abbrev /terminate get exec\n";
-
- void WriteEpsfProcSetDef ()
- {
- DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetDef, strlen(EpsfProcSetDef));
- }
-
- void WriteEpsfProcSetInit ()
- {
- DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetInit, strlen(EpsfProcSetInit));
- }
-
- void WriteEpsfProcSetTerm ()
- {
- DPSWritePostScript(DPSGetCurrentContext(), EpsfProcSetTerm, strlen(EpsfProcSetTerm));
- }
-
- /*
- * Writes the Adobe Illustrator 88 imported document operator.
- */
- void WriteEpsfIllustratorBeg(NXRect *bounds, NXRect *boundsOrig, float rotation, char *filename)
- {
- float a = 1.0, b = 0.0,
- c = 0.0, d = 1.0,
- sx = 1.0, sy = 1.0;
-
- NXPoint t;
-
- DPSContext ctxt;
-
- if (boundsOrig->size.width)
- sx = bounds->size.width/boundsOrig->size.width;
- if (boundsOrig->size.height)
- sy = bounds->size.height/boundsOrig->size.height;
-
- if (rotation != 0.0)
- {
- a = d = (float) cos(rotation);
- b = c = (float) sin(rotation);
- c = -c;
- }
- a = a * sx;
- b = b * sx;
- c = c * sy;
- d = d * sy;
-
- t.x = bounds->origin.x - boundsOrig->origin.x * sx;
- t.y = bounds->origin.y - boundsOrig->origin.y * sy;
-
- ctxt = DPSGetCurrentContext();
- DPSPrintf(ctxt, "\n0 g 0 i 0 J 0 j 1 w 10 M [] 0 d\n");
- DPSPrintf(ctxt, "[%g %g %g %g %g %g] %g %g %g %g", a, b, c, d, t.x, t.y,
- boundsOrig->origin.x, boundsOrig->origin.y,
- boundsOrig->origin.x + boundsOrig->size.width,
- boundsOrig->origin.y + boundsOrig->size.height);
- if (filename)
- DPSPrintf(ctxt, " (%s)", filename);
- else
- DPSPrintf(ctxt, " ( )");
- DPSPrintf(ctxt, " `\n");
-
- DPSPrintf(ctxt, "%%%%BeginDocument: ");
- if (filename)
- DPSPrintf(ctxt, "%s", filename);
- DPSPrintf(ctxt,"\n");
- }
-
- void WriteEpsfIllustratorInclude(char *name)
- {
- DPSContext ctxt;
-
- ctxt = DPSGetCurrentContext();
- DPSPrintf(ctxt, "%%%%IncludeFile: ");
- if (name)
- DPSPrintf(ctxt, "%s", name);
- DPSPrintf(ctxt, "\n");
- }
-
- void WriteEpsfIllustratorEnd()
- {
- DPSContext ctxt;
-
- ctxt = DPSGetCurrentContext();
- DPSPrintf(ctxt, "%%%%EndDocument\n");
- DPSPrintf(ctxt, "~\n\n");
- }
-
- void WriteEpsfResource(id list, int i, int j)
- {
- int k, count,
- linelen, datalen, commentlen;
-
- char comment[EPSF_MAXCOMMENTSUB];
-
- NXAtom data;
-
- DPSContext ctxt;
-
- count = [list count];
- if (count)
- {
- ctxt = DPSGetCurrentContext();
- GetDocumentComment(comment, i, j);
- DPSPrintf(ctxt, comment);
-
- linelen = commentlen = strlen(comment);
- for (k = 0; k < count; k++)
- {
- data = (NXAtom) [list objectAt:k];
- datalen = strlen(data);
- if (datalen + linelen > EPSF_MAXCOMMENT)
- {
- /* Prevents an infinite loop for a single large datalen. */
- if (commentlen != linelen)
- {
- DPSPrintf(ctxt, "\n%%%%+");
- linelen = commentlen = 3;
- }
- }
-
- DPSPrintf(ctxt, " %s", data);
- linelen += datalen;
- }
-
- DPSPrintf(ctxt, "\n");
- }
- }
-
- static char GetBlackWhiteAt(NXBitmapImageRep *image, int x, int y)
- {
- int bps, spp, amask;
-
- unsigned char gray;
-
- spp = [image samplesPerPixel];
- bps = [image bitsPerSample];
-
- amask = (1 << bps) - 1; // 1, 3, 15, 255 for bps = 1, 2, 4, 8
- if ([image isPlanar])
- {
- int pixel = x * bps;
- int byteLoc = [image bytesPerRow] * y + (pixel >> 3);
- int bitLoc = pixel & 7;
- gray = ((*([image data]+byteLoc)) >> (8 - bitLoc - bps)) & amask;
- }
- else
- {
- unsigned char *byteLoc = [image data] + [image bytesPerRow] * y;
- int bitLoc = x * bps * spp;
- gray = ((byteLoc[bitLoc >> 3]) >> (8 - (bitLoc & 7) - bps)) & amask;
- }
-
- return (gray >> 1 ? 0 : 1);
- }
-
- void WriteEpsfPreview(id image)
- {
- int byte, orbyte;
-
- int i, j, width, height,
- pos, bytes;
-
- DPSContext ctxt;
-
- if (image)
- {
- ctxt = DPSGetCurrentContext();
-
- width = [image pixelsWide];
- height = [image pixelsHigh];
- DPSPrintf(ctxt, "%%%%BeginPreview: %d %d %d %d",
- width, height, 1, (((width-1)/8)/MAX_BYTES + 1) *height);
- for (i = 0; i < height; i++)
- {
- DPSPrintf(ctxt, "\n%% ");
- pos = 7;
- byte = 0;
- bytes = 0;
- for (j = 0; j < width; j++, pos--)
- {
- orbyte = GetBlackWhiteAt(image, j, i) << pos;
- byte = byte | orbyte;
- if (pos == 0 || j == width - 1)
- {
- bytes++;
- if (bytes > MAX_BYTES)
- {
- bytes = 0;
- DPSPrintf(ctxt, "\n%% ");
- }
- DPSPrintf(ctxt, "%02x", byte);
- pos = 8;
- byte = 0;
- }
- }
- }
- DPSPrintf(ctxt, "\n%%%%EndPreview\n\n");
- }
- }
-
- /*
- * This does nothing in the way of error recovery. It is used to demonstrate the
- * problems on not using a separate context. Eps files with errors can potentially
- * harm the application's context. The recommended approach is to use
- * the NXEPSImageRep object to image the file.
- */
- int WriteEpsf(const char *name, NXRect *bounds, NXRect *boundsOrig)
- {
- BOOL trace;
-
- int error, len, maxlen;
-
- char *data;
-
- NXStream *stream;
-
- DPSContext ctxt;
-
- trace = [NXApp tracingFlag];
- error = EPSF_OK;
- stream = NXMapFile(name, NX_READONLY);
- if (stream)
- {
- NXGetMemoryBuffer(stream, &data, &len, &maxlen);
- if (data && len)
- {
- ctxt = DPSGetCurrentContext();
- error = EPSF_WRITEERROR;
- NX_DURING
- DPSTraceContext(ctxt, trace);
-
- PSWBeginEpsf();
- PSWSetEpsf(bounds->origin.x, bounds->origin.y, bounds->size.width,
- bounds->size.height, boundsOrig->origin.x, boundsOrig->origin.y,
- boundsOrig->size.width, boundsOrig->size.height, 0);
-
- DPSPrintf(ctxt, "%%%%BeginDocument: %s\n", name);
- DPSPrintf(ctxt, "%%%% ...Included EPS file here... \n");
-
- DPSTraceContext(ctxt, NO);
- DPSWritePostScript(ctxt, data, len);
- DPSTraceContext(ctxt, trace);
-
- DPSPrintf(ctxt, "%%%%EndDocument\n");
-
- PSWEndEpsf();
- DPSTraceContext(ctxt, NO);
-
- DPSFlushContext(ctxt);
-
- error = EPSF_OK;
- NX_HANDLER
- if (NXLocalHandler.code == dps_err_ps)
- LogEpsfError(&NXLocalHandler);
- else
- NX_RERAISE();
- NX_ENDHANDLER
- }
- }
-
- return error;
- }
-